package com.jinghang.Zookeeper.java_api;

import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.ACL;

import java.io.IOException;
import java.util.List;

/**
 *  1.同步异步 操作节点 demo演示
 *  2.同学抄写2遍代码之后，讲解异步类创建方法，不用死记代码
 *
 *  实例化Zookeeper对象(zk),调用zk的方法对节点操作
 *
 *
 *
 */
public class _13_0_ZKNodeOperator implements Watcher {

    private ZooKeeper zookeeper = null;

    public static final String zkServerPath = "hadoop000:2181";
    public static final Integer timeout = 5000;

    public _13_0_ZKNodeOperator() {
    }

    public _13_0_ZKNodeOperator(String connectString) {
        try {
            zookeeper = new ZooKeeper(connectString, timeout, new _13_0_ZKNodeOperator());
        } catch (IOException e) {
            e.printStackTrace();
            if (zookeeper != null) {
                try {
                    zookeeper.close();
                } catch (InterruptedException e1) {
                    e1.printStackTrace();
                }
            }
        }
    }





    public static void main(String[] args) throws Exception {
        _13_0_ZKNodeOperator zkServer = new _13_0_ZKNodeOperator(zkServerPath);

        // 同步创建zk节点  Ids.OPEN_ACL_UNSAFE：代表权限等级 -->> 任何人都能操作该节点
        //zkServer.createZKNodeSyn("/syn_node", "hello".getBytes(), Ids.OPEN_ACL_UNSAFE);
        //设置节点数据
        //Stat status  = zkServer.getZookeeper().setData("/syn_node", "xyz".getBytes(), 0);
        //System.out.println("Version: " + status.getVersion());

        //异步创建zk节点
        //zkServer.createZKNodeAsyn("/asyn_node", "hello".getBytes(), Ids.OPEN_ACL_UNSAFE);





        zkServer.createZKNodeSyn("/test-delete-node", "123".getBytes(), Ids.OPEN_ACL_UNSAFE);
        //同步删除节点，不能添加返回信息
		//zkServer.getZookeeper().delete("/test-delete-node", 0);

        String ctx = "{'delete':'success'}";
        //异步删除节点，可以定义返信息
        zkServer.getZookeeper().delete("/test-delete-node", 0, new _13_2_DeleteCallBack(), ctx);
        Thread.sleep(3000);
    }

    /**
     * @Title: ZKOperatorDemo.java
     * @Description: 同步创建zk节点
     */
    public void createZKNodeSyn(String path, byte[] data, List<ACL> acls) {

        String result = "";
        try {
            /**
             * 同步或者异步创建节点，都不支持子节点的递归创建，异步有一个callback函数
             * 参数：
             * path：创建的路径
             * data：存储的数据的byte[]
             * acl：控制权限策略
             * 			Ids.OPEN_ACL_UNSAFE --> world:anyone:cdrwa
             * 			CREATOR_ALL_ACL --> auth:user:password:cdrwa
             * createMode：节点类型, 是一个枚举
             * 			PERSISTENT：持久节点
             * 			PERSISTENT_SEQUENTIAL：持久顺序节点
             * 			EPHEMERAL：临时节点
             * 			EPHEMERAL_SEQUENTIAL：临时顺序节点
             */
            //同步创建节点，主线线程创建节点，返回节点路径
            result = zookeeper.create(path, data, acls, CreateMode.PERSISTENT);
            new Thread().sleep(3000);
            System.out.println("创建节点：\t" + result + "\t成功...");
            new Thread().sleep(3000);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * @Title: ZKOperatorDemo.java
     * @Description: 异步创建zk节点
     */
    public void createZKNodeAsyn(String path, byte[] data, List<ACL> acls) {

        String result = "";
        try {
            String ctx = "{'create':'success'}";
            //异步创建节点，其他线程创建节点，返回值为void
            zookeeper.create(path, data, acls, CreateMode.PERSISTENT, new _13_1_CreateCallBack(), ctx);
            new Thread().sleep(5000);
            System.out.println("创建节点：\t" + result + "\t成功...");
            new Thread().sleep(5000);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }



    public ZooKeeper getZookeeper() {
        return zookeeper;
    }

    public void setZookeeper(ZooKeeper zookeeper) {
        this.zookeeper = zookeeper;
    }

    @Override
    public void process(WatchedEvent event) {
    }
}

